package com.vdg.lockphotos.app;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;

import com.vdg.lockphotos.data.Album;
import com.vdg.lockphotos.data.Photo;
import com.vdg.lockphotos.gridphotos.GridPhotoAdapter;
import com.vdg.lockphotos.notify.OnLoadAlbumsListener;
import com.vdg.lockphotos.notify.OnLoadListHiddenImageListener;
import com.vdg.lockphotos.notify.OnLoadListImageListener;
import com.vdg.lockphotos.util.Utilities;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;

public class ApplicationManagement {
	public static ApplicationManagement sInstance;
	private Context mContext;
	private OnLoadListImageListener mOnLoadListImageListener;
	private OnLoadAlbumsListener mOnLoadAlbumsListener;
	private OnLoadListHiddenImageListener mOnLoadListHiddenImageListener;
	private Handler mHandler = new Handler();
	private String mSelectedAlbumName;

	public ApplicationManagement(Context context) {
		mContext = context;
	}

	public static ApplicationManagement getInstance(Context context) {
		if (sInstance == null) {
			sInstance = new ApplicationManagement(context);
		}
		return sInstance;
	}

	public void hidePhotos(final ArrayList<Photo> listPhotos,
			final String albumUrl) {
		new Thread() {
			@Override
			public void run() {
				boolean isUpdateInMedia = true;
				if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
					isUpdateInMedia = false;
				}
				// TODO Auto-generated method stub
				for (Photo photo : listPhotos) {
					try {
						photo.hide(mContext, isUpdateInMedia);
						Photo.addHiddenInSharedPreferences(mContext, photo);
						// scanFile(mContext, photo.getImageUrl());
					} catch (NameNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (isUpdateInMedia) {
					reloadData();
				} else {
					Utilities.scanMedia(mContext);

				}
				Log.v("debug", "hide photo sucess");
				// Utilities.scanMedia(mContext, albumUrl);
				// scanFile(mContext, photo.getImageUrl());
				super.run();
			}
		}.start();
	}

	public void unHidePhotos(final ArrayList<Photo> listPhotos) {
		new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				boolean isUpdateInMedia = true;
				if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
					isUpdateInMedia = false;
				}
				for (Photo photo : listPhotos) {
					String imageUrl = Photo.removeHiddenInSharedPreferences(
							mContext, photo);
					Log.v("debug", "return image url = " + imageUrl);
					if (imageUrl != null && !imageUrl.equals("")) {
						photo.setImageUrl(imageUrl);
						photo.Show(mContext, isUpdateInMedia);
					}
				}
				// Utilities.scanMedia(mContext,
				// Utilities.getDataDir(mContext) + "/.images/");
				// scanFile(mContext, Utilities.getDataDir(mContext)
				// + "/.images/");
				if (isUpdateInMedia) {
					reloadData();
				} else {
					Utilities.scanMedia(mContext);

				}
				// loadHideImages();
				// loadAllImage();
				super.run();
			}
		}.start();
	}

	public void loadAllImage(OnLoadListImageListener listener, String albumName) {
		mSelectedAlbumName = albumName;
		mOnLoadListImageListener = listener;
		if (mOnLoadListImageListener != null)
			mOnLoadListImageListener.onStartLoad();
		final ArrayList<Photo> listResult = new ArrayList<Photo>();
		final Cursor cc = mContext.getContentResolver().query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				new String[] { MediaStore.Images.Media.DISPLAY_NAME,
						MediaStore.Images.Media.DATA }, null, null,
				MediaStore.Images.Media.DISPLAY_NAME + " ASC");
		if (cc != null) {
			new Thread() {
				public void run() {
					if (cc.moveToFirst()) {
						do {
							if ((new File(cc.getString(1))).getParentFile()
									.getName().equals(mSelectedAlbumName)) {
								Photo photo = new Photo(cc.getString(0),
										cc.getString(1));
								listResult.add(photo);
							}
						} while (cc.moveToNext());
					} else {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								if (mOnLoadListImageListener != null)
									mOnLoadListImageListener.onLoadFailed();
							}
						});
					}
					cc.close();
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							if (mOnLoadListImageListener != null) {
								mOnLoadListImageListener
										.onLoadSucessed(listResult);
								Log.i("ExternalStorage", "onloadsucessed1");
							}
							Log.i("ExternalStorage", "onloadsucessed");
						}
					});
				}
				// dissmiss dialog
			}.start();
		} else {
			if (mOnLoadListImageListener != null)
				mOnLoadListImageListener.onLoadFailed();
		}
	}

	public void loadAllAlbums() {
		if (mOnLoadAlbumsListener != null)
			mOnLoadAlbumsListener.onStartLoad();
		final ArrayList<Album> listAlbum = new ArrayList<Album>();
		final Cursor cc = mContext.getContentResolver().query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				new String[] { MediaStore.Images.Media.DISPLAY_NAME,
						MediaStore.Images.Media.DATA }, null, null,
				MediaStore.Images.Media.DISPLAY_NAME + " ASC");
		if (cc != null) {
			new Thread() {
				public void run() {
					if (cc.moveToFirst()) {
						do {
							String alName = (new File(cc.getString(1)))
									.getParentFile().getName();
							Album album = new Album(alName);
							if (!Album.isExist(listAlbum, alName)) {
								listAlbum.add(album);
							}
							Photo photo = new Photo(cc.getString(0),
									cc.getString(1));
							photo.setAlbumName(alName);
							Album.insetToListAlbum(listAlbum, photo);
						} while (cc.moveToNext());
					} else {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								if (mOnLoadAlbumsListener != null)
									mOnLoadAlbumsListener.onLoadFailed();
							}
						});
					}
					cc.close();
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							if (mOnLoadAlbumsListener != null)
								mOnLoadAlbumsListener.onLoadSucessed(listAlbum);
						}
					});
				}
				// dissmiss dialog
			}.start();
		} else {
			if (mOnLoadAlbumsListener != null)
				mOnLoadAlbumsListener.onLoadFailed();
		}
	}

	public void loadAllAlbums(OnLoadAlbumsListener listener) {
		mOnLoadAlbumsListener = listener;
		if (mOnLoadAlbumsListener != null)
			mOnLoadAlbumsListener.onStartLoad();
		final ArrayList<Album> listAlbum = new ArrayList<Album>();
		final Cursor cc = mContext.getContentResolver().query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				new String[] { MediaStore.Images.Media.DISPLAY_NAME,
						MediaStore.Images.Media.DATA }, null, null,
				MediaStore.Images.Media.DISPLAY_NAME + " ASC");
		if (cc != null) {
			new Thread() {
				public void run() {
					if (cc.moveToFirst()) {
						do {
							String albumName = (new File(cc.getString(1)))
									.getParentFile().getName();
							if (!Album.isExist(listAlbum, albumName)) {
								Album album = new Album(albumName);
								listAlbum.add(album);
							}
							Photo photo = new Photo(cc.getString(0),
									cc.getString(1));
							// Log.e("mNames[i]", ":" + cc.getColumnName(3)
							// + " : " + cc.getColumnName(1));
							photo.setAlbumName(albumName);
							Album.insetToListAlbum(listAlbum, photo);
						} while (cc.moveToNext());
					} else {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								if (mOnLoadAlbumsListener != null)
									mOnLoadAlbumsListener.onLoadFailed();
							}
						});
					}
					cc.close();
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							if (mOnLoadAlbumsListener != null)
								mOnLoadAlbumsListener.onLoadSucessed(listAlbum);
						}
					});
				}
				// dissmiss dialog
			}.start();
		} else {
			if (mOnLoadAlbumsListener != null)
				mOnLoadAlbumsListener.onLoadFailed();
		}
	}

	public void loadAllImage() {
		Log.i("ExternalStorage", "onloadsucessed11");
		if (mOnLoadListImageListener != null) {
			mOnLoadListImageListener.onStartLoad();
		}
		final ArrayList<Photo> listResult = new ArrayList<Photo>();
		final Cursor cc = mContext.getContentResolver().query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				new String[] { MediaStore.Images.Media.DISPLAY_NAME,
						MediaStore.Images.Media.DATA }, null, null,
				MediaStore.Images.Media.DISPLAY_NAME + " ASC");
		Log.i("ExternalStorage", "onloadsucessed12");
		if (cc != null) {
			new Thread() {
				public void run() {
					if (cc.moveToFirst()) {
						do {
							if ((new File(cc.getString(1))).getParentFile()
									.getName().equals(mSelectedAlbumName)) {
								Photo photo = new Photo(cc.getString(0),
										cc.getString(1));

								listResult.add(photo);
							}
						} while (cc.moveToNext());
					} else {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								if (mOnLoadListImageListener != null) {
									Log.i("ExternalStorage", "onloadsucessed16");
									mOnLoadListImageListener.onLoadFailed();
								}
								Log.i("ExternalStorage", "onloadsucessed17");
							}
						});
					}
					cc.close();
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							if (mOnLoadListImageListener != null) {
								mOnLoadListImageListener
										.onLoadSucessed(listResult);
								Log.i("ExternalStorage", "onloadsucessed1");
							}
							Log.i("ExternalStorage", "onloadsucessed");
						}
					});
				}
				// dissmiss dialog
			}.start();
		} else {
			if (mOnLoadListImageListener != null) {
				mOnLoadListImageListener.onLoadFailed();
				Log.i("ExternalStorage", "onloadsucessed14");
			}
			Log.i("ExternalStorage", "onloadsucessed13");
		}
	}

	public void loadHideImages() {
		if (mOnLoadListHiddenImageListener != null)
			mOnLoadListHiddenImageListener.onStartLoad();
		final ArrayList<Photo> listResult = new ArrayList<Photo>();
		new Thread() {
			public void run() {
				File images = null;
				try {
					images = new File(Utilities.getDataDir(mContext)
							+ "/.images");
				} catch (NameNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					if (mOnLoadListHiddenImageListener != null) {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								mOnLoadListHiddenImageListener.onLoadFailed();
							}
						});
					}
					return;
				}
				File[] imagelist = images.listFiles(new FilenameFilter() {
					public boolean accept(File dir, String name) {
						return true;
						// return ((name.endsWith(".jpg")) ||
						// (name.endsWith(".png")));
					}
				});
				if (imagelist == null || imagelist.length == 0) {
					if (mOnLoadListHiddenImageListener != null) {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								mOnLoadListHiddenImageListener
										.onLoadSucessed(listResult);
							}
						});
					}
					return;
				}
				for (int i = 0; i < imagelist.length; i++) {
					Photo pho = new Photo(imagelist[i].getName(), null);
					pho.setHiddenUrl(imagelist[i].getAbsolutePath());
					listResult.add(pho);
				}
				if (mOnLoadListHiddenImageListener != null) {
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							mOnLoadListHiddenImageListener
									.onLoadSucessed(listResult);
						}
					});
				}
			}
		}.start();
	}

	public void regisOnLoadHiddenListener(OnLoadListHiddenImageListener listener) {
		mOnLoadListHiddenImageListener = listener;
	}

	public void loadHideImages(OnLoadListHiddenImageListener listener) {
		this.mOnLoadListHiddenImageListener = listener;
		if (mOnLoadListHiddenImageListener != null)
			mOnLoadListHiddenImageListener.onStartLoad();
		final ArrayList<Photo> listResult = new ArrayList<Photo>();
		new Thread() {
			public void run() {
				File images = null;
				try {
					images = new File(Utilities.getDataDir(mContext)
							+ "/.images");
				} catch (NameNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					if (mOnLoadListHiddenImageListener != null) {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								mOnLoadListHiddenImageListener.onLoadFailed();
							}
						});
					}
					return;
				}
				File[] imagelist = images.listFiles(new FilenameFilter() {
					public boolean accept(File dir, String name) {
						return true;
						// return ((name.endsWith(".jpg")) ||
						// (name.endsWith(".png")));
					}
				});
				if (imagelist == null || imagelist.length == 0) {
					if (mOnLoadListHiddenImageListener != null) {
						mHandler.post(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								mOnLoadListHiddenImageListener
										.onLoadSucessed(listResult);
							}
						});
					}
					return;
				}
				for (int i = 0; i < imagelist.length; i++) {
					Photo pho = new Photo(imagelist[i].getName(), null);
					pho.setHiddenUrl(imagelist[i].getAbsolutePath());
					listResult.add(pho);
				}
				if (mOnLoadListHiddenImageListener != null) {
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							mOnLoadListHiddenImageListener
									.onLoadSucessed(listResult);
						}
					});
				}
			}
		}.start();
	}

	BroadcastReceiver mExternalStorageReceiver;
	boolean mExternalStorageAvailable = false;
	boolean mExternalStorageWriteable = false;

	void updateExternalStorageState() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			mExternalStorageAvailable = mExternalStorageWriteable = true;
		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			mExternalStorageAvailable = true;
			mExternalStorageWriteable = false;
		} else {
			mExternalStorageAvailable = mExternalStorageWriteable = false;
		}
		handleExternalStorageState(mExternalStorageAvailable,
				mExternalStorageWriteable);
	}

	public void handleExternalStorageState(boolean mExternalStorageAvailable,
			boolean mExternalStorageWriteable) {
		Log.v("debug", "writeable = " + mExternalStorageAvailable + "---"
				+ mExternalStorageWriteable);
		if (mExternalStorageAvailable == true
				&& mExternalStorageWriteable == true) {
			loadAllAlbums();
			loadAllImage();
			loadHideImages();
		}
	}

	public void startWatchingExternalStorage() {
		Log.v("test", "start: ");
		mExternalStorageReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				Log.v("test", "Storage: " + intent.getData());
				updateExternalStorageState();
			}
		};
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
		// filter.addAction(Intent.ACTION_MEDIA_REMOVED);
		filter.addDataScheme("file");
		mContext.registerReceiver(mExternalStorageReceiver, filter);
		updateExternalStorageState();
	}

	public void stopWatchingExternalStorage() {
		mContext.unregisterReceiver(mExternalStorageReceiver);
	}

	public void reloadData() {
		mHandler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				loadAllImage();
				loadAllAlbums();
				loadHideImages();
			}
		});

	}
	// public void scanFile(Context context, String url) {
	// Log.i("ExternalStorage", "start scaner " + url + ":");
	// mHandler.post(new Runnable() {
	//
	// @Override
	// public void run() {
	// // TODO Auto-generated method stub
	// loadAllImage();
	// loadAllAlbums();
	// loadHideImages();
	// }
	// });
	//
	// MediaScannerConnection.scanFile(context, new String[] { url }, new
	// String[] {"image/"},
	// new MediaScannerConnection.OnScanCompletedListener() {
	// public void onScanCompleted(String path, Uri uri) {
	// Log.i("ExternalStorage", "Scanned " + path + ":");
	// Log.i("ExternalStorage", "-> uri=" + uri);
	// mHandler.post(new Runnable() {
	//
	// @Override
	// public void run() {
	// // TODO Auto-generated method stub
	// loadAllImage();
	// loadAllAlbums();
	// loadHideImages();
	// }
	// });
	//
	// }
	// });
}
